home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / x11 / tuner / public.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-10  |  28.1 KB  |  1,010 lines

  1. /*
  2. %    PUBLIC . C
  3. %
  4. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5.  
  6. This software is copyright (C) by the Lawrence Berkeley Laboratory.
  7. Permission is granted to reproduce this software for non-commercial
  8. purposes provided that this notice is left intact.
  9.  
  10. It is acknowledged that the U.S. Government has rights to this software
  11. under Contract DE-AC03-765F00098 between the U.S.  Department of Energy
  12. and the University of California.
  13.  
  14. This software is provided as a professional and academic contribution
  15. for joint exchange. Thus, it is experimental, and is provided ``as is'',
  16. with no warranties of any kind whatsoever, no support, no promise of
  17. updates, or printed documentation. By using this software, you
  18. acknowledge that the Lawrence Berkeley Laboratory and Regents of the
  19. University of California shall have no liability with respect to the
  20. infringement of other copyrights by any part of this software.
  21.  
  22. For further information about this notice, contact William Johnston,
  23. Bld. 50B, Rm. 2239, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
  24. (wejohnston@lbl.gov)
  25.  
  26. For further information about this software, contact:
  27.     Jin Guojun
  28.     Bld. 50B, Rm. 2275, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
  29.     g_jin@lbl.gov
  30.  
  31. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  32. %
  33. %        initial & run time handlers (updating)
  34. %    Including:
  35. %        Button1_On(), SaveImage(), YesOrNo(), WaitOk(),
  36. %        CreateTuner(), Set_Monitor(), histochange(),
  37. %        ChangePanelCmap(), DrawPanel(), Get_Note_Input(),
  38. %        DisplayMessage(),
  39. %        Exposure_handler(), PickUpColor(), Toggle_Info(),
  40. %        HistoHandle(), Histo_Setting(), Map_HistoWin(img)
  41. %
  42. % AUTHOR:    Guojun Jin - LBL    4/1/1991
  43. */
  44.  
  45. #ifndef    RLE_IMAGE
  46. #define    RLE_IMAGE
  47. #endif
  48.  
  49. #ifndef    Cursor_Flushing
  50. #define    Cursor_Flushing    15
  51. #endif
  52.  
  53. #include "tuner.h"
  54.  
  55. bool    rw_set, start_fast = 1;    /* how to get system color */
  56. int    fnt_r, fnt_g, fnt_b;
  57. PopMenu    *ctrlmenu, *paramenu, *filemenu, *fontmenu;
  58. Panel    *NoteWin, *InfoWin;
  59. Button    *MsgButton;
  60. InterpMap    *IM;    /* interpolation matrix */
  61. PressButton    *YesButt, *NoButt, *OkButt, *AbortButt;
  62. XWindowAttributes    gwattrs;
  63. char    *BN1[] = {"fore", "back", "linear"},
  64.     *BNF[] = {"FILE", "Load", "Save"},
  65.     *NF[] = {"OFF", "ON"},
  66.     *HST[] = {"histogram", "Scale", "Set", "Neg", "Grid"},
  67.     *DUP[] = {"Analysis", "Update"},
  68.     *NOTEMSG[] = {"*   CHANGE ETA SCALE   *"};
  69.  
  70. #ifndef    HISTO_BACKGROUND
  71. #define    HISTO_BACKGROUND    lightGray
  72. #endif
  73.  
  74. #define    Dpy1        Monitor[1].dpy
  75. #define    Screen1        Monitor[1].screen
  76.  
  77. /*===============================================
  78. %    public routines for color and b/w    %
  79. ===============================================*/
  80. void
  81. Exposure_handler(expose, img)
  82. XExposeEvent    *expose;
  83. Image    *img;
  84. {
  85. register Window    exp_win=expose->window;
  86.     if (expose->type != Expose)
  87.         return;    /*    generated by XCopyArea    */
  88.     if (img && exp_win == img->win)
  89.         win_exposure(expose, img, (int(*)())Draws);
  90.     else if (img && exp_win == img->icon)
  91.         XPutImage(img->dpy, img->icon, img->igc, img->icon_image,
  92.             0, 0, 0, 0, img->icon_width, img->icon_height);
  93.     else if (exp_win == Epanel->win)
  94.         DrawPanel();
  95.     else if (exp_win == InfoWin->win)    Toggle_Info(0);
  96.     else if (exp_win == histinfo.his->win)
  97.         win_exposure(expose, histinfo.his, DrawVMark);
  98.     else if (exp_win == NoteWin->win)
  99.         DisplayMessage(NoteWin, NULL, 0, True);
  100.     else    message("strange exposure win %d\n", exp_win);
  101.     DEBUGMESSAGE("expose event x= %d y= %d width= %d height= %d\n",
  102.             expose->x, expose->y, expose->width, expose->height);
  103. }
  104.  
  105. /*=======================================================
  106. %    positive cquire to quire the colormap        %
  107. %    negtive cquire to quire user color table    %
  108. =======================================================*/
  109. void
  110. dumpColor(dpy, cmap, cquire)
  111. Display    *dpy;
  112. Colormap cmap;
  113. {
  114. XColor    qcolor;
  115. register int    i;
  116.  
  117. if (!cquire)    return;
  118. msg("colormap = %d\n", cmap);
  119. if (cquire>0)
  120.     for (i=0; i < cquire; i++)    {
  121.     qcolor.pixel = (u_long) i;
  122.     XQueryColor(dpy, cmap, &qcolor);
  123.     message("vct[%3d]:(%3u) red =%8X, green =%8X, blue =%8X\n", i,
  124.         qcolor.pixel, qcolor.red, qcolor.green, qcolor.blue);
  125.     }
  126. else    for (i=0; i<-cquire; i++)
  127.     message("gtable[%3d]:(%3u) red =%8x, green =%8x, blue =%8x\n", i,
  128.         graylevel[i].pixel, graylevel[i].red,
  129.         graylevel[i].green, graylevel[i].blue);
  130. }
  131.  
  132.  
  133. void
  134. ChangeSlider(img, slider, s1, s2, equ_b, rel_b)
  135. Image    *img;
  136. Slider    **slider, *s1, *s2;
  137. Button    *equ_b, *rel_b;
  138. {
  139. EraseSlider(*slider);
  140. switch (img->curve) {
  141. case ETAForeGD:
  142. case ETABackGD:
  143.     *slider = s1;    /* ESlider */
  144.     SetSBarRPos(*slider, img->curve ? img->bgrd : img->fgrd, 1);
  145.     break;
  146. case ETALinear:
  147. case ETALinear | ETAHistoEq:
  148.     *slider = s2;    /* LSlider */
  149.     SetSBarRPos(*slider, img->linearlow, 1);
  150.     SetSBarRPos(*slider, img->linearup, 2);
  151.     ButtonState(equ_b /*heqButt*/) = img->curve & ETAHistoEq;
  152.     break;
  153. default:msg("ETA %d\n", img->curve);
  154. }
  155. DrawSlider(*slider);
  156. SliderInfo(*slider, lightGray);
  157. ButtonState(rel_b) = img->curve & 0x7;
  158. DrawButton(rel_b);    /* EButton */
  159. }
  160.  
  161. void
  162. SetShowFramePos(img, f_b, reset)
  163. Image    *img;
  164. Button    *f_b;
  165. {
  166.     sprintf(f_b->bname[PosFRAME], fb_format, img->fn+1, img->frames);
  167.     if (reset)    ButtonState(f_b)=RESETSTATE;
  168.     DrawButton(f_b /*fButton*/);
  169. }
  170.  
  171. SetPanelColor(dpy, cmap, cp, depth, fast)
  172. Display    *dpy;
  173. Colormap    cmap;
  174. XColor    cp[];
  175. {
  176. if (fast>1)    {
  177.     Red = GetUserColor(cp, depth, 255, 0, 0);
  178.     Green = GetUserColor(cp, depth, 0, 255, 0);
  179.     Blue = GetUserColor(cp, depth, 0, 0, 255);
  180.     Yellow = GetUserColor(cp, depth, 255, 255, 0);
  181. } else {
  182.     Red = GetCloseColor(dpy, cmap, depth, NULL, 255, 15, 15);
  183.     Green = GetCloseColor(dpy, cmap, depth, NULL, 15, 255, 20);
  184.     Blue = GetCloseColor(dpy, cmap, depth, NULL, 15, 15, 255);
  185.     Yellow = GetCloseColor(dpy, cmap, depth, NULL, 255, 255, 20);
  186. }
  187. if (Visible==darkGray) {
  188.     Visible = GetGray(dpy, cmap, depth, 144);
  189.     darkGray = GetGray(dpy, cmap, depth, 80);
  190.     lightGray = GetGray(dpy, cmap, depth, 160);
  191.     Gray = GetGray(dpy, cmap, depth, 192);
  192. }
  193. else    Light = GetUserGray(cp, depth, 224);
  194.  
  195. MGray = GetGray(dpy, cmap, depth, 96);
  196.  
  197. if (verbose)
  198.     fprintf(stderr, "[%d] greylevels %d\n\
  199.     W=%d, Blk=%d, MG=%u LG=%u Gy=%u, Lt=%u; Y=%X, R=%X, G=%X, B=%X\n",
  200.     cmap, ncolors, White, Black, MGray, lightGray, Light, Gray,
  201.     Yellow, Red, Green, Blue);
  202. }
  203.  
  204. /*=======================================================================
  205. %  End of each line is always cut at a spcae except the word length    %
  206. %    exceeding line width, then a hyphen is added at broken place    %
  207. =======================================================================*/
  208. void
  209. DisplayMessage(mw, msgsp, sp_limit, refresh)
  210. Panel    *mw;
  211. char    *msgsp;
  212. {
  213. int    nl;
  214. register int    i, ll, sp, sl=mw->width/mw->font_w-2, l, mp;
  215. char    *sbuf = zalloc(sizeof(*sbuf), sl+2, "sbuf");
  216. static    char*    msgp;
  217. static    int    resp;
  218.  
  219. if (!refresh)
  220.     TopWindow(mw, 1),
  221.     resp = sp_limit,
  222.     msgp = msgsp;    /* save current string */
  223. else if (!msgsp)     /* use saved string */
  224.     msgsp = msgp,
  225.     sp_limit = resp;
  226.  
  227.     l = strlen(msgsp);
  228.     for (i=mp=ll=0; mp < l; mp += ++nl) {
  229.         nl = ((int)strchr(msgsp+mp, '\n') - (int)msgsp) - mp;
  230.         if (nl<0 || nl>l)
  231.             nl = l - mp;
  232.         if (nl > sl)    ll += nl / sl;
  233.         ll++;
  234.     }
  235.     i = mw->height / mw->font_h;
  236.     if (ll > i)    ll = i;
  237.     sp = (i - ll - 1) * mw->font_h / ll;
  238.     if (sp_limit && sp > sp_limit)
  239.         sp = sp_limit;
  240.     if (sp > (mw->height>>2))
  241.         sp = mw->font_h;
  242.     XSetForeground(mw->dpy, mw->gc, white1);
  243.     for (i=mp=0; i<ll; i++)    {
  244.         nl = ((int)strchr(msgsp+mp, '\n') - (int)msgsp) - mp + 1;
  245.         if (i+1==ll) {
  246.             l = strlen(msgsp+mp);
  247.             if (l > sl)    l = sl,    ll++;
  248.         }
  249.         else    if (nl<0 || nl>sl)    l = sl;
  250.             else    l = nl;
  251.         strncpy(sbuf, msgsp+mp, l);    sbuf[l] = 0;
  252.         if (i+1 != ll && (strchr(sbuf, ' ') || strchr(sbuf, '\n')))
  253.             while (sbuf[l] != ' ' && sbuf[l] != '\n')    l--;
  254.         if (l)
  255.             XDrawString(mw->dpy, mw->win, mw->gc,
  256.             mw->font_w, (i+1)*(mw->font_h+sp), msgsp+mp, l);
  257.         if (msgsp[mp+l] && msgsp[mp+l] != ' ' && msgsp[mp+l] != '\n')
  258.             XDrawString(mw->dpy, mw->win, mw->gc,
  259.             mw->font_w*(l+1), (i+1)*(mw->font_h+sp), "-", 1);
  260.         else    ++l;
  261.         mp += l;
  262.     }
  263.     free(sbuf);
  264. XFlush(mw->dpy);
  265. }
  266.  
  267. WaitOk(b, sp, line_h)
  268. PressButton*    b;
  269. char*    sp;
  270. {
  271. register XEvent    *xe;
  272.  
  273. if (!b)    b = OkButt;
  274. xe = &b->pan->event;
  275.  
  276. DisplayMessage(NoteWin, sp, line_h, 0);
  277. DrawPressButton(b);
  278. while (!XCheckMaskEvent(b->pan->dpy, ButtonPressMask, xe))
  279.     if (XCheckMaskEvent(b->pan->dpy, ExposureMask, xe))
  280.     Exposure_handler(xe, NULL),    DrawPressButton(b);
  281. HidingPanel(NoteWin);
  282. return    (b==OkButt);
  283. }
  284.  
  285. YesOrNo(sp, line_h)
  286. char*    sp;
  287. {
  288. register XEvent    *xe = &YesButt->pan->event;
  289. register int    state = 2;
  290.  
  291. DisplayMessage(NoteWin, sp, line_h, 0);
  292. DrawPressButton(YesButt);
  293. DrawPressButton(NoButt);
  294. while (abs(state) >> 1) {
  295.     while (!XCheckMaskEvent(YesButt->pan->dpy, ButtonPressMask, xe))
  296.         if (XCheckMaskEvent(YesButt->pan->dpy, ExposureMask, xe))
  297.         Exposure_handler(xe, NULL),
  298.         DrawPressButton(YesButt),
  299.         DrawPressButton(NoButt);
  300.     if (ButtonPressed(YesButt, xe))        state = 1;
  301.     else if (ButtonPressed(NoButt, xe))    state = 0;
  302. }
  303. HidingPanel(NoteWin);
  304. return    state;
  305. }
  306.  
  307. Get_Note_Input(buf, buf_size, sp_limit, info, i_color, dmsg)
  308. char    *buf, *info;
  309. {
  310.     DisplayMessage(NoteWin, buf, sp_limit, 0);
  311.     if (info)
  312.         DispInfo(NoteWin, 4, info, i_color);
  313.     if (dmsg)
  314.         DrawButton(MsgButton);
  315.     buf[0] = 0;
  316.     return    TextLine(MsgButton, buf, buf_size,
  317.             info ? (strlen(info)+1) * fontWidth : fontWidth,
  318.         Exposure_handler, pic, num_images); /* only global usage */
  319. }
  320.  
  321. void
  322. Toggle_Info(s)
  323. char    *s;
  324. {
  325. static    int    state;
  326. static    char*    sp;
  327. register int    old = !s;
  328.  
  329. if (!old)
  330.     sp = s;
  331. if (old || (state = !state))
  332.     DisplayMessage(InfoWin, sp, 8, old);
  333. else    HidingPanel(InfoWin);
  334. }
  335.  
  336. void
  337. SetPanelItemColor()
  338. {
  339. Set_Panel(CSlider, SLIDER_COLOR, Green, Red, lightGray);
  340. Set_Panel(ESlider, SLIDER_COLOR, Blue, white1, Visible);
  341. Set_Panel(LSlider, SLIDER_COLOR, Red, white1, lightGray);
  342. Set_Panel(QSlider, SLIDER_COLOR, Red, Green, white1);
  343. Set_Panel(QButton, BUTTON_COLOR, Visible, Light, Green);
  344. Set_Panel(DButton, BUTTON_COLOR, Visible, Light, Green);
  345. Set_Panel(EButton, BUTTON_COLOR, lightGray, Yellow, Green);
  346. Set_Panel(FButton, BUTTON_COLOR, Visible, Light, Green);
  347. Set_Panel(fButton, BUTTON_COLOR, Visible, Light, Green);
  348. Set_Panel(hButton, BUTTON_COLOR, Visible, Light, Green);
  349. Set_Panel(Interpolate, BUTTON_COLOR, Visible, Light, Yellow);
  350. Set_Panel(ZButton, BUTTON_COLOR, Visible, Light, Yellow);
  351. Set_Panel(RstButt, PRESS_BUTTON_COLOR, Gray, lightGray, -1);
  352. Set_Panel(rfsButt, PRESS_BUTTON_COLOR, lightGray, Gray, Red);
  353. Set_Panel(heqButt, PRESS_BUTTON_COLOR, Light, lightGray, -1);
  354. Set_Panel(YesButt, PRESS_BUTTON_COLOR, Light, lightGray, -1);
  355. Set_Panel(NoButt, PRESS_BUTTON_COLOR, Light, lightGray, -1);
  356. ctrlmenu->bgcolor=paramenu->bgcolor=filemenu->bgcolor = Light;    /*?*/
  357. }
  358.  
  359. void
  360. ChangePanelCmap(img)
  361. U_IMAGE*    img;
  362. {
  363. register int    i=Dpy != Dpy1;    /* point default cmap */
  364. if (i)    return;
  365.  
  366.     XGetWindowAttributes(Epanel->dpy, Epanel->win, &gwattrs);
  367.     if (gwattrs.colormap != img->colormap) {
  368.     register int    BaseGL=Monitor[i].cmap==img->colormap ? VCTEntry : 0;
  369. #ifdef    _DEBUG_
  370.     msg("\nsave colormap [%u] %X\n", firstmap, gwattrs.colormap);
  371.     msg("gl77 = %05u %05u %05u\n",
  372.         graylevel[77].red, graylevel[77].green, graylevel[77].blue);
  373. #endif
  374.     if (gwattrs.colormap && firstmap)
  375.         XStoreColors(Epanel->dpy, firstmap, graylevel, ncolors);
  376.  
  377.     for (i=img->entries; i--;)
  378.         graylevel[i].pixel = i + BaseGL;
  379.     XQueryColors(img->dpy, firstmap=img->colormap,
  380.         graylevel, ncolors=img->entries);
  381. #ifdef    _DEBUG_
  382.     msg("new colormap = %X [%u]\n", img->colormap, firstmap);
  383.     msg("gl77 = %05u %05u %05u\n",
  384.         graylevel[77].red, graylevel[77].green, graylevel[77].blue);
  385. #endif
  386.     XSetWindowColormap(Epanel->dpy, Epanel->win, firstmap);
  387.     XSetWindowColormap(NoteWin->dpy, NoteWin->win, firstmap);
  388.     XSetWindowColormap(InfoWin->dpy, InfoWin->win, firstmap);
  389.     XSetWindowColormap(ctrlmenu->dpy, ctrlmenu->win, firstmap);
  390.     XSetWindowColormap(paramenu->dpy, paramenu->win, firstmap);
  391.     XSetWindowColormap(filemenu->dpy, filemenu->win, firstmap);
  392.     XInstallColormap(Epanel->dpy, firstmap);
  393.     if (ButtonState(QButton) && img->dpy_depth < 24) {
  394.         Visible = darkGray;
  395.         Light = GetGray(img->dpy, img->colormap, img->entries, 224);
  396.         white1 = GetGray(img->dpy, img->colormap, img->entries, 248);
  397.         SetPanelColor(img->dpy, img->colormap, graylevel, img->entries, 2);
  398.         SetPanelItemColor();
  399.     }
  400.     }
  401. }
  402.  
  403. PickUpColor(img, r, g, b)
  404. Image    *img;
  405. int    *r, *g, *b;
  406. {
  407. byte    *p;
  408. int    v=SetParameterWin(img, img->event, img->font_h, 0);
  409.  
  410. DisplayMessage(NoteWin,
  411.     "move mouse to choose a color\nrelease button to pick it up", 0, 0);
  412.     while (!ImageEvent(img, ButtonReleaseMask))
  413.     if (ImageEvent(img, PointerMotionMask))
  414.         ParameterWin(img, &histinfo, img->event->xbutton.x,
  415.             img->event->xbutton.y, v, False);
  416.     v = img->width;
  417.     p = img->data + img->channels * v * (img->event->xbutton.y
  418. #ifndef    SCROLLBAR_on_CANVAS
  419.         + img->y0) + img->x0 +
  420. #else
  421.         ) +
  422. #endif
  423.             img->event->xbutton.x;
  424.     if (img->channels==1){
  425.     v = *p;
  426.     if (img->in_cmap)
  427.         *r = img->in_cmap[0][v],
  428.         *g = img->in_cmap[1][v],
  429.         *b = img->in_cmap[2][v];
  430.     }
  431.     else    {
  432.     *r = *p;
  433.     *g = p[v];
  434.     *b = p[v << 1];
  435.     v = (*r * RED_to_GRAY + *g * GREEN_to_GRAY + *b * BLUE_to_GRAY) >> 8;
  436.     }
  437. HidingPanel(NoteWin);
  438. return    v;
  439. }
  440.  
  441. void
  442. MakeTrueColorPanel()
  443. {
  444.     black1 = 0;
  445.     white1 = 0xFFFFFF;
  446.     gray1 = 0x808080;
  447.     Red = 0x00FF;
  448.     Green = 0x00FF00;
  449.     Blue = 0xFF0000;
  450.     Yellow = 0x00FFFF;
  451.     Visible = 0x909090;
  452.     darkGray = 0x505050;
  453.     lightGray = 0xA0A0A0;
  454.     Gray = 0xC0C0C0;
  455.     Light = 0xE0E0E0;
  456.     MGray = 0x606060;
  457. }
  458.  
  459. void
  460. Set_Monitor(mnt, dpy, dpy1, cmap)
  461. WinAttribute*    mnt;
  462. Display    *dpy, *dpy1;
  463. Colormap    cmap;
  464. {
  465. if (mnt == NULL)
  466.     mnt = &Monitor[0];
  467. if (!dpy1)
  468.     dpy1 = dpy;
  469. mnt->dpy = dpy;
  470. mnt->screen = XDefaultScreen(dpy);
  471. if (!cmap || dpy == dpy1)
  472.     mnt->cmap = DefaultColormap(dpy, mnt->screen);
  473. else    mnt->cmap = cmap;
  474. mnt->root = XDefaultRootWindow(dpy, mnt->screen);
  475. mnt->visual = XDefaultVisual(dpy, mnt->screen);
  476. mnt->dpy_depth = XDefaultDepth(dpy, mnt->screen);
  477.  
  478. mnt++;
  479. mnt->dpy = dpy1;
  480. mnt->screen = XDefaultScreen(dpy1);
  481. if (!cmap || dpy != dpy1)
  482.     cmap = DefaultColormap(dpy1, mnt->screen);
  483. mnt->cmap = cmap;
  484. mnt->root = XDefaultRootWindow(dpy1, mnt->screen);
  485. mnt->visual = XDefaultVisual(dpy1, mnt->screen);
  486. mnt->dpy_depth = XDefaultDepth(dpy1, mnt->screen);
  487.  
  488. mnt--;    /* always let Monitor[0] be color & Monitor[1] be mono    */
  489. if (mnt->dpy_depth < mnt[1].dpy_depth)    {    /* if not, swap    */
  490. register int    tmp;
  491.     mnt->dpy = dpy1;
  492.     mnt[1].dpy = dpy;
  493.     tmp = mnt->screen;
  494.     mnt->screen = mnt[1].screen;
  495.     mnt[1].screen = tmp;
  496.     mnt[1].cmap = mnt->cmap;
  497.     mnt->cmap = cmap;
  498.     tmp = (int) mnt->root;
  499.     mnt->root = mnt[1].root;
  500.     mnt[1].root = (Window)tmp;
  501.     tmp = (int) mnt->visual;
  502.     mnt->visual = mnt[1].visual;
  503.     mnt[1].visual = (Visual*) tmp;
  504.     tmp = mnt->dpy_depth;
  505.     mnt->dpy_depth = mnt[1].dpy_depth;
  506.     mnt[1].dpy_depth = tmp;
  507. }
  508. if (ncolors > 1<<mnt->dpy_depth)
  509.     ncolors = 1<<mnt->dpy_depth;
  510. }
  511.  
  512. BuildImage(imgf, name, w, h, mfrm, IType, OType, IBflag)
  513. Image    **imgf;
  514. char    *name;
  515. {
  516.     CreateImage(imgf, name, Monitor, w, h, StdIconWidth, I_Mask, IBflag);
  517.     /*    I_Mask | LeaveWindowMask    */
  518.     format_init(*imgf, IType, OType, -1, Progname, "A5-2");
  519.     XDefineCursor((*imgf)->dpy, (*imgf)->win, cursor);
  520.     XSetWindowBackground((*imgf)->dpy, (*imgf)->win, MGray);
  521.     if (mfrm)    {
  522.         if ((*imgf)->marray)    free((*imgf)->marray);
  523.         (*imgf)->marray = zalloc(sizeof(Mregister), mfrm, "3m_array");
  524.     }
  525.     if ((*imgf)->data)    free((*imgf)->data);
  526.     (*imgf)->hist = (int*)nzalloc(HistoSize, sizeof(*(*imgf)->hist), "hist");
  527.     XMapWindow((*imgf)->dpy, (*imgf)->frame);
  528.     XMapWindow((*imgf)->dpy, (*imgf)->win);
  529.  
  530. #ifdef    EXTENDED_COLOR
  531.     if ((*imgf)->dpy_depth != 8)    {
  532.     extern    int    log2_levels;
  533.     register Image*    i = *imgf;
  534.         if (OType==HIPS)
  535.             i->mono_img = True;
  536.         if (!i->visual_class)
  537.             i->visual_class = -1;
  538.         i->lvls = 1 << (log2_levels=8);
  539.     /*    init_img_info(i, 0, OType, cmn_hd.color_dpy);    */
  540.         find_appropriate_visual(i);
  541.         get_dither_colors(i);
  542.         init_color(i);        /* build dither array here */
  543.         choose_scanline_converter(i);
  544.     }
  545. #endif
  546. }
  547.  
  548. CreateTuner(img, ela_scale, panel_bg, map_panel)
  549. U_IMAGE    *img;
  550. PColor    panel_bg;
  551. {
  552. register int    i=1<<Monitor[1].dpy_depth, j;
  553.  
  554. arrow = XCreateFontCursor(Dpy, XC_sb_down_arrow);
  555.  
  556. #ifdef    _DEBUG_
  557. message("%d graylevel\n", ncolors /* -(~newmap&VCTEntry) */);
  558. message("dpy=%x, dpy1=%x, screen=%d, screen1=%d\n", Dpy, Dpy1, Screen, Screen1);
  559. #endif
  560.  
  561. /*    must be after color allocated    */
  562. if (!precision)    precision = 384;
  563.  
  564. if (img->dpy_depth < 24)    {
  565.     black1 = XBlackPixel(Dpy1, Screen1);
  566.     white1 = gray1 = XWhitePixel(Dpy1, Screen1);
  567.     if (i == 2)    darkGray = i;
  568.     SetPanelColor(Dpy1, Monitor[1].cmap, graylevel,
  569.         MIN(i, ncolors), start_fast);
  570. }
  571. else    MakeTrueColorPanel();
  572.  
  573. if (panel_bg < 2)
  574.     panel_bg = darkGray;
  575. if (x_regions < 2 || x_regions > MAX_ITP_LEVEL)
  576.     x_regions = 2;
  577. if (y_regions < 2 || y_regions > MAX_ITP_LEVEL)
  578.     y_regions = 2;
  579. i = MAX_ITP_LEVEL * MAX_ITP_LEVEL;    /* taking 64K memory */
  580. j = MaxColors;
  581. IM = (InterpMap*)nzalloc(i, sizeof(*IM), "IM");
  582. while (i--)
  583.     IM[i].lkt = (LKT*)nzalloc(j, sizeof(LKT), "lkts");
  584.  
  585. lkt = histinfo.lkt = (LKT*)zalloc(j*(img->color_dpy?3:1), sizeof(*lkt), "lkt");
  586. if (img->color_dpy)
  587.     for (i=0; i<MaxColors; i++)
  588.     lkt[i] = lkt[j+i] = lkt[(j<<1)+i] = i;
  589.  
  590. histinfo.hist = (int*)nzalloc(HistoSize, sizeof(*(histinfo.hist)), "hist");
  591. CreateImage(&(histinfo.his), "Histogram", Monitor, HistoSize+(BFRAME<<1),
  592.     (HistoSize+(BFRAME<<1)) * (img->color_dpy ? 3 : 1), 32,
  593.     I_Mask | ExposureMask, 1);
  594. histinfo.his->color_dpy = img->mid_type==RLE;
  595. histinfo.his->channels = img->dpy_channels ? img->dpy_channels : 1;
  596.  
  597. XDefineCursor(Dpy, histinfo.his->win, arrow);
  598. XSetWindowBackground(Dpy, histinfo.his->win, MGray);
  599. XSelectInput(Dpy, histinfo.his->win, ExposureMask | I_Mask);
  600. return    Panel_init(&Monitor[1], ela_scale, panel_bg, map_panel);
  601. }
  602.  
  603. void
  604. DrawPanel()
  605. {
  606.     /* it will be changed. */
  607. int    pan_fgd = slider->pan->gc->values.foreground;
  608.     DrawSlider(slider);
  609.     DrawSlider(CSlider);
  610.     DrawSlider(QSlider);
  611.     DrawButton(EButton);
  612.     DrawButton(FButton);
  613.     DrawButton(fButton);
  614.     DrawButton(hButton);
  615.     DrawButton(ZButton);
  616.     DrawButton(QButton);
  617.     DrawButton(DButton);
  618.     DrawButton(Interpolate);
  619.     DrawPressButton(heqButt);
  620.     DrawPressButton(rfsButt);
  621.     DrawPressButton(RstButt);
  622. XSetForeground(slider->pan->dpy, slider->pan->gc, pan_fgd);
  623. }
  624.  
  625. Button1_On(xbutton, fb)
  626. XButtonEvent    *xbutton;
  627. int    *fb;
  628. {
  629. if (ButtonPressed(RstButt, xbutton))    return    OnResetButton;
  630. if (*fb=OnSliderBar(slider, xbutton))    return    OnETASlider;
  631. if (*fb=OnSliderBar(CSlider, xbutton))    return    OnClipSlider;
  632. if (*fb=OnSliderBar(QSlider, xbutton))    return    OnQuanSlider;
  633. if (OnButton(hButton, xbutton)>0)    return    OnHistButton;
  634. if (OnButton(ZButton, xbutton)>0)    return    OnZcntButton;
  635. if (OnButton(QButton, xbutton)>0)    return    OnQuanButton;
  636. if (OnButton(fButton, xbutton)>0)    return    OnFrameButton;
  637. if (OnButton(EButton, xbutton)>0)    return    OnETAButton;
  638. if (OnButton(DButton, xbutton)>0)    return    OnDataButton;
  639. if (OnButton(Interpolate, xbutton)>0)    return    OnInterpolate;
  640. if (ButtonPressed(rfsButt, xbutton))    return    OnRefresh;
  641. if (ButtonPressed(heqButt, xbutton))    return    OnHEQButton;
  642. return    EOF;
  643. }
  644.  
  645.  
  646. SaveImage(img)
  647. Image    *img;
  648. {
  649. char    buf[128];
  650. register int    len;
  651.  
  652. TopWindow(Epanel, 1);
  653. DrawPanel();    XFlush(Epanel->dpy);
  654. sprintf(buf, "SAVE %s before Close it ? y/n", img->name);
  655. len = (strlen(buf)+2) * Epanel->font_w;
  656. DispInfo(Epanel, 0, buf, white1);
  657. buf[0] = 0;
  658. TextLine(fButton, buf, sizeof(buf), len, Exposure_handler, pic, num_images);
  659.  
  660. if (buf[0] != 'n'){
  661.     ButtonState(FButton) = FileSave;
  662.     FileAccess(&img, 1, 1);
  663.     }
  664. }
  665.  
  666. /*=======================================================
  667. %    public histo_handle for both color and b/w    %
  668. =======================================================*/
  669. void
  670. histchange(b, img, histinfo)
  671. Button    *b;
  672. Image    *img;
  673. HistoInfo *histinfo;
  674. {
  675. register int    i;
  676. switch (ButtonState(b)) {
  677. case HistBgNeg:    {
  678.     register byte    *hbp = histinfo->his->img_buf;
  679.     i = histinfo->his->width * histinfo->his->height;
  680.         for (; --i; hbp++)
  681.             *hbp = -1 - *hbp;
  682.     }
  683.     XPutImage(histinfo->his->dpy, histinfo->his->win, histinfo->his->gc,
  684.         histinfo->his->image, 0, 0,
  685.         0, 0, histinfo->his->width, histinfo->his->height);
  686.     histinfo->neg = ~histinfo->neg;
  687.     break;
  688. case HistBgGrid:
  689.     if (histinfo->grids)
  690.         histinfo->grids=0;
  691.     else    histinfo->grids=5;    /* number of grids */
  692.     HistoHandle(img, histinfo, HISTO_BACKGROUND);
  693. }
  694. }
  695.  
  696. Histo_Setting(img, lbuf)
  697. U_IMAGE    *img;
  698. char    *lbuf;
  699. {
  700. register int    i;
  701.     if (ButtonState(hButton) > HistScaleSet)
  702.         histchange(hButton, img, &histinfo);
  703.     else {
  704.         sprintf(lbuf, "maximum histo = %d, set %s", img->mmm.maxcnt,
  705.         ButtonState(hButton)==HistScaleSelf ? "sacle" :
  706.                 "maximum value");
  707.         i = (strlen(lbuf)+2) * Epanel->font_w;
  708.         DispInfo(Epanel, 0, lbuf, white1);
  709.         histinfo.scale = lbuf[0] = 0;
  710.         TextLine(hButton, lbuf, sizeof(lbuf), i,
  711.         Exposure_handler, pic, num_images);
  712.         i = atoi(lbuf);
  713.         img->setscale = ButtonState(hButton)==HistScaleSet;
  714.         switch (ButtonState(hButton)){
  715.         case HistScaleSelf:
  716.         if (img->color_dpy)
  717.             img->mmm.maxcnt = img->marray[img->fn %
  718.                     img->channels].maxcnt;
  719.         else
  720.             img->mmm.maxcnt = img->marray[img->fn].maxcnt;
  721.         if (i)    histinfo.scale = i;
  722.         break;
  723.         case HistScaleSet:
  724.         if (i < 0)    img->mmm.maxcnt = img->marray[0].maxcnt;
  725.         else if (i>row)    img->mmm.maxcnt = i;
  726.         }
  727.         HistoHandle(img, &histinfo, HISTO_BACKGROUND);
  728.     }
  729.     ButtonState(hButton) = RESETSTATE;
  730.     DrawButton(hButton);
  731. }
  732.  
  733. Map_HistoWin(img)
  734. U_IMAGE    *img;
  735. {
  736.     if (histinfo.map){
  737.         XUnmapWindow(histinfo.his->dpy, histinfo.his->frame);
  738.         histinfo.map = histinfo.his->sub_img = 0;
  739.     }
  740.     else    {
  741.         XMapWindow(histinfo.his->dpy, histinfo.his->frame);
  742. #ifdef    SCROLLBAR_on_CANVAS
  743.         XMapWindow(histinfo.his->dpy, histinfo.his->win);
  744. #endif
  745.         histinfo.map = !histinfo.change;
  746.         HistoHandle(img, &histinfo, HISTO_BACKGROUND);
  747.         histinfo.change=histinfo.map=1;
  748.     }
  749. }
  750.  
  751. HistoHandle(img, hinfo, grid_color)
  752. Image    *img;
  753. HistoInfo *hinfo;
  754. {
  755. static    int    last_channels;
  756. int    channel, grid, grids, bground, border, bar, frac_grid, maxcnt,
  757.     *newhist=(int*)zalloc(HistoSize*img->channels, sizeof(*newhist), "newhist");
  758. register int    i, j, k, image_size, image_frame, *hp;
  759.  
  760. if (hinfo->map){
  761.     border = grid = grid_color;
  762.     bground = HBGround;
  763.     if (hinfo->neg) {
  764.         border = grid = hinfo->neg - grid;
  765.         bground = hinfo->neg - bground;
  766.     }
  767.     image_size=HistoSize, image_frame=HistoSize+(BFRAME<<1);
  768.     if (hinfo->grids)
  769.         grids = image_size / hinfo->grids;
  770.     else    grids = image_size;
  771.     frac_grid = image_size % grids;
  772.  
  773.     for (channel=0; channel<img->channels; channel++)    {
  774.     {
  775.     register LKT*    lktp = (LKT*)hinfo->lkt + channel * HistoSize;
  776.     register int    *histp = hinfo->histp + channel * image_size;
  777.     k = img->mmm.min;    j = img->mmm.max - k + 1;
  778.     for (i=0, hp=newhist + channel*HistoSize; i<j; i++)
  779.         hp[lktp[i]] += histp[i+k];
  780.     }
  781.     if (img->setscale | img->color_dpy)
  782.         maxcnt = img->mmm.maxcnt;
  783.     else    maxcnt = img->marray[img->fn].maxcnt;
  784.     if (!maxcnt)    maxcnt = 8192;
  785. #ifdef    _DEBUG_
  786.     if (verbose>1)    dump_tbl(hp, image_size, 4, "hp");
  787. #endif
  788.  
  789.     if (img->channels == 1)
  790.         bar = Green;
  791.     else switch (channel) {
  792.         case 0:    bar = Red;    break;
  793.         case 1:    bar = Green;    break;
  794.         case 2:    bar = Blue;
  795.         }
  796.  
  797.     if (img->dpy_depth == 8) {
  798.     register byte*    bhp = (byte*)hinfo->his->img_buf +
  799.                 channel*image_frame*image_frame;
  800.         for (i=0; i<image_frame; i++)
  801.         for (j=0; j<image_frame; j++)
  802.             if (!j || j>=image_frame-BFRAME ||
  803.             !i || i>=image_frame-BFRAME)
  804.             *bhp++ = border;
  805.             else if (!((i-frac_grid) % grids) || !(j % grids))
  806.             *bhp++ = grid;
  807.             else
  808.             *bhp++ = bground;
  809.         for (i=BFRAME; i<image_size+BFRAME; i++){    /* horizontal process */
  810.         bhp = (byte*)hinfo->his->img_buf + i + image_frame *
  811.             (channel * image_frame + image_size);
  812.         j = (image_size * hp[i-BFRAME] << hinfo->scale) / maxcnt;
  813.         if (j > image_size)    j = image_size;
  814.  
  815.         for (k=0; k<j; k++) {    /* vertical process    */
  816.             *bhp = bar;
  817.             bhp -= image_frame;
  818.         }
  819.         }
  820.     } else    {
  821.     register int*    ihp = (int*)hinfo->his->img_buf +
  822.                 channel*image_frame*image_frame;
  823.         for (i=0; i<image_frame; i++)
  824.         for (j=0; j<image_frame; j++)
  825.             if (!j || j>=image_frame-BFRAME ||
  826.             !i || i>=image_frame-BFRAME)
  827.             *ihp++ = border;
  828.             else if (!((i-frac_grid) % grids) || !(j % grids))
  829.             *ihp++ = grid;
  830.             else
  831.             *ihp++ = bground;
  832.         for (i=BFRAME; i<image_size+BFRAME; i++)    {
  833.         ihp = (int*)hinfo->his->img_buf + i + image_frame *
  834.             (channel * image_frame + image_size);
  835.         j = (image_size * hp[i-BFRAME] << hinfo->scale) / maxcnt;
  836.         if (j > image_size)    j = image_size;
  837.  
  838.         for (k=0; k<j; k++) {    /* vertical process    */
  839.             *ihp = bar;
  840.             ihp -= image_frame;
  841.         }
  842.         }
  843.     }
  844.     }
  845.     free(newhist);
  846.     if (last_channels != img->channels)
  847.     last_channels = img->channels,
  848.     hinfo->his->resize_h = last_channels * 258,
  849.     XResizeWindow(hinfo->his->dpy, hinfo->his->frame,
  850.         image_frame, image_frame*img->channels);
  851.     XPutImage(hinfo->his->dpy, hinfo->his->win, hinfo->his->gc, hinfo->his->image,
  852.     0, 0, 0, 0, image_frame, image_frame*img->dpy_channels);
  853.     if (hinfo->his->sub_img)
  854.     DrawVMark(hinfo->his, 0, 0);
  855. }
  856. XFlush(hinfo->his->dpy);
  857. hinfo->change=hinfo->map;
  858. }
  859.  
  860. LineScan(p, scan, color, lktp, w, min, tc)
  861. register byte    *p, *scan;
  862. register XColor    *color;
  863. register LKT*    lktp;
  864. register int    w;
  865. {
  866. if (tc)    while(w--)
  867.     scan[w] = color[dgt[lktp[(p[w] - min)&0xFF]]].pixel;
  868. else    while(w--)
  869.     scan[w] = dgt[lktp[(p[w] - min)&0xFF]];
  870. }
  871.  
  872. /*    ANNOTATE an image by given colors    */
  873. void
  874. RestoreArea(img, x, y, c, r, w, h)
  875. Image    *img;
  876. {
  877. register int    x0 = (x += c * w),    y0 = (y += r * h);
  878. #ifndef    SCROLLBAR_on_CANVAS
  879. x0 += img->x0;    y0 += img->y0;
  880. #endif
  881. XPutImage(img->dpy, img->win, img->gc, img->image, x0, y0, x, y, w, h);
  882. }
  883.  
  884. static    int    Acolor, Afont;
  885.  
  886. Annotation(img, y0, keysym, stat)
  887. Image    *img;
  888. int    *y0;
  889. KeySym    *keysym;
  890. XComposeStatus    *stat;
  891. {
  892. int    max_char, max_cinr, num_cols, num_rows, sp, x, y, len, fnt_w, fnt_h;
  893. char    *buf = nzalloc(32, 32, "annotate");
  894. XEvent    *event = img->event;
  895.  
  896.     if (img->dpy_depth > 8)
  897.         return    WaitOk(0, "no annotation on true color device", 0);
  898.     Acolor = img->color_form==CFM_SCF ? CloseColor_in_Map
  899.         (img->in_cmap, img->cmaplen, fnt_r, fnt_g, fnt_b, precision) :
  900.     (RED_to_GRAY*fnt_r + GREEN_to_GRAY*fnt_g + BLUE_to_GRAY*fnt_b) >> 8;
  901.     if (!img->color_dpy)
  902.         Acolor >= 2;
  903.     TopWindow(img, 0);    Exposure_handler(event, img);
  904.  
  905.     while (1)    {
  906.     fnt_w = img->font_w,    fnt_h = img->font_h;
  907.     switch (WaitButtonPress_n_InfoImage(img, &histinfo, y0, arrow))    {
  908.     case Button1:
  909.     max_cinr = num_cols = num_rows = sp = 0;
  910.     x = event->xbutton.x;    y = event->xbutton.y;
  911.     max_char = (img->width - x) / fnt_w;
  912.  
  913.     while (1)    {
  914.         FlushingCursor(img, Exposure_handler, &img, 1, x + num_cols*fnt_w,
  915.             y+num_rows*fnt_h, fnt_w, 2, Cursor_Flushing, 1);
  916.         if (!(len=XLookupString(event, buf+sp, 1024-sp, keysym, stat)))
  917.             continue;
  918.  
  919.         buf[sp + len] = 0;
  920.         if ((len=buf[sp]) == BS)    {
  921.             if (num_cols)    {
  922.             sp--;    num_cols--;
  923.             } else if (num_rows)    {
  924.             sp--;    num_rows--;
  925.             while((len=sp - num_cols) && buf[len-1] != CR)
  926.                 num_cols++;
  927.             }    else    continue;
  928.             RestoreArea(img, x, y-fnt_h, num_cols, num_rows, fnt_w, fnt_h);
  929.         }
  930.         else    {
  931.             if (++num_cols == max_char || len == CR)    {
  932.             if (buf[sp] != CR)    {
  933.                 buf[sp+1] = buf[sp];
  934.                 buf[sp] = CR;
  935.             }
  936.             num_rows++;
  937.             num_cols = 0;
  938.             }
  939.             if (max_cinr < num_cols)
  940.             max_cinr = num_cols;
  941.             if (len == Esc || len == CTRL_Y || ++sp >= 1024)
  942.             break;
  943.             else if (len != CR)
  944.             XSetForeground(img->dpy, img->gc, Acolor),
  945.             XDrawString(img->dpy, img->win, img->gc,
  946.             x+(num_cols-1)*fnt_w, y+num_rows*fnt_h, buf+sp-1, 1);
  947.         }
  948.     }
  949.     if (buf[sp] != CR)    num_rows++;
  950.     if (len != Esc)
  951.         if (img->o_type==HIPS)
  952.         superimpose_add_elem(img, buf, Acolor, -1,
  953.             y, x, num_rows, max_cinr);
  954.         else CombineImage_Draws(img, x, y, fnt_w*max_cinr, fnt_h*num_rows,
  955.             Acolor);
  956.     else    RestoreArea(img, x, y-fnt_h, 0, 0, fnt_w * max_cinr,
  957.             fnt_h * num_rows + XStringBaseHigh);
  958.     break;
  959.  
  960.     case Button2:
  961.     if ((len=GetNew_Img_Font(img)) < 0)
  962.         Afont = len;
  963.     else    Acolor = len;
  964.     break;
  965.  
  966.     case Button3:
  967.     default:    free(buf);    return;
  968.     }
  969.     }
  970. }
  971.  
  972. GetNew_Img_Font(img)
  973. Image    *img;
  974. {
  975. int    i = PopingMenu(fontmenu, MENUF_PKCOLOR, Exposure_handler, &img, 1);
  976.  
  977.     /* the list number in this popmenu is start from 0 rather 1    */
  978.     if (--i < MENUF_1stFONT)
  979.         if (i == MENUF_PKCOLOR)
  980.         return    PickUpColor(img, &fnt_r, &fnt_g, &fnt_b);
  981.         else    return    i;
  982.     else if (i < MENUF_UNDO)
  983.         SetFontGetSize(img, fontlist[i]);
  984. return    ~i;
  985. }
  986.  
  987.  
  988. WaitButtonPress_n_InfoImage(img, hinfo, y0, cursor)
  989. Image    *img;
  990. HistoInfo    *hinfo;
  991. int    *y0;
  992. Cursor    cursor;
  993. {
  994.     /* clear previous button events    */
  995.     RemoveImageEvent(img, ButtonAction);
  996.  
  997.     *y0 = SetParameterWin(img, img->event, img->font_h, 0);
  998.     XDefineCursor(img->dpy, img->win, cursor);
  999.     while (!ImageEvent(img, ButtonPressMask))    {
  1000.         RemoveImageEvent(img, ButtonReleaseMask);
  1001.         if (ImageEvent(img, PointerMotionMask))
  1002.             ParameterWin(img, hinfo, img->event->xbutton.x,
  1003.                 img->event->xbutton.y, *y0, False);
  1004.         while (ImageEvent(img, ExposureMask))
  1005.             Exposure_handler(img->event, img);
  1006.     }
  1007.     ClearParameterWin(img, *y0);
  1008. return    img->event->xbutton.button;
  1009. }
  1010.